import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;

import javax.xml.ws.http.HTTPException;


public class HttpClient {
    /*
    客户端模拟POST文件上传
    参考博客：https://blog.csdn.net/weixin_30387339/article/details/98902763
              https://blog.csdn.net/alen_en/article/details/79481227
              https://blog.csdn.net/zhangkun987123/article/details/104926035
    FileName:文件上传地址，绝对路径
    FileUrl:文件服务器地址
    */
    public String upLoad(String FileName,String FileUrl){
        String fileName = FileName;//文件地址
        //"http://127.0.0.1:8090/api/upload"
        String fileUrl =FileUrl;//文件服务器地址
        try {
                // 换行符  
                final String newLine = "\r\n";
                final String boundaryPrefix = "--";
                // 定义数据分隔线  
                String BOUNDARY = "========7d4a6d158c9";
                // 服务器的域名  
                URL url = new URL(fileUrl);
                System.out.println("================连接==================");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                System.out.println("================连接成功==================");
                // 设置为POST情  
                conn.setRequestMethod("POST");
                // 发送POST请求必须设置如下两行  
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setUseCaches(false);
                // 设置请求头参数  
                /*
                *   POST /api/feed/ HTTP/1.1
                    Accept-Encoding: gzip
                    Content-Length: 225873
                    Content-Type: multipart/form-data; boundary=OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp
                    Host: www.myhost.com
                    Connection: Keep-Alive
                * */
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("Charsert", "UTF-8");
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
                OutputStream out = new DataOutputStream(conn.getOutputStream());
                System.out.println("================上传文件==================");
                // 上传文件  
                File file = new File(fileName);
                StringBuilder sb = new StringBuilder();
                sb.append(boundaryPrefix);
                sb.append(BOUNDARY);
                sb.append(newLine);
                /*
                * --OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp
                    Content-Disposition: form-data; name="lng"
                    Content-Type: text/plain; charset=UTF-8
                    Content-Transfer-Encoding: 8bit
                *
                * */
                // 文件参数
                // 设置上传的文件名称
                fileName = fileName.trim();
                fileName = fileName.substring(fileName.lastIndexOf("/")+1);
                sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"" + newLine);
                //告诉浏览器响应的对象类型，application/octet-stream表示不清楚当前文件的类型，需要将其保存为一个文件
                sb.append("Content-Type:application/octet-stream");
                // 参数头设置完以后需要两个换行，然后才是参数内容  
                sb.append(newLine);
                sb.append(newLine);
                // 将参数头的数据写入到输出流中  
                out.write(sb.toString().getBytes());
                // 数据输入流,用于读取文件数据
                DataInputStream in = new DataInputStream(new FileInputStream( file));
                byte[] bufferOut = new byte[1024*1024];
                int bytes = 0;
                // 每次读1MB数据,并且将文件数据写入到输出流中  
                while ((bytes = in.read(bufferOut)) != -1) {
                    out.write(bufferOut, 0, bytes);
                }
                // 最后添加换行  
                out.write(newLine.getBytes());
                in.close();

                // 定义最后数据分隔线，即--加上BOUNDARY再加上--  
                byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes();
                // 写上结尾标识  
                out.write(end_data);
                out.flush();
                out.close();

                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {
                    System.out.println("服务器接收数据成功！");
                } else {
                    System.out.println(responseCode+"服务器接收数据失败！");
                }
                //获取服务端返回的数据
                InputStream inout = conn.getInputStream();
                ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
                int bytesout = 0;
                byte[] bufferout = new byte[1024];
                while ((bytesout = inout.read(bufferout)) != -1) {
                    infoStream.write(bufferout, 0, bytesout);
                }
                inout.close();
                infoStream.flush();
                infoStream.close();
                //对JSON格式的返回数据进行处理
                String json = infoStream.toString("utf-8");
                if(json!=null){
                    JSONObject jsonObj = JSONObject.parseObject(json);
                    String uuid = jsonObj.getString("data");
                    return uuid;
                }
         } catch (Exception e) {
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
        }
        return null;
    }

    //客户端模拟文件下载
    //参考博客：https://www.jianshu.com/p/2456ee303ea5
    public void download(String uuid){
        //下载文件请求接口地址
        String downFileUrl = "http://127.0.0.1:8090/api/file/"+uuid;
        try {
            URL url = new URL(downFileUrl);
            System.out.println("================连接==================");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            System.out.println("================连接成功==================");
            //设置超时间为3秒
            conn.setConnectTimeout(3*1000);
            //防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

            //处理服务端响应异常
            int responseCode = conn.getResponseCode();
            if(conn.getResponseCode() == 410){
                throw new IOException();
            }

            //获取响应头部
            Map<String, List<String>> map = conn.getHeaderFields();
            List<String> infos = map.get("content-disposition");
            String fileName = infos.get(0);
            //得到原始文件名称
            fileName = fileName.substring(fileName.indexOf('=')+1);
            //得到输入流
            InputStream inputStream = conn.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while((len = inputStream.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.close();
            //获取自己数组
            byte[] getData = bos.toByteArray();

            //文件保存位置
            File saveDir = new File("D:/qiyuesuo/download");
            if(!saveDir.exists()){
                saveDir.mkdir();
            }
            File file = new File(saveDir+File.separator + fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if(fos!=null){
                fos.close();
            }
            if(inputStream!=null){
                inputStream.close();
            }
            System.out.println("================下载文件成功==================");
        }catch (Exception e){
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
    }

    //客户端模拟获取文件信息
    public void getFileInfo(String uuid){
        //获取文件元信息请求接口地址
        String downFileUrl = "http://127.0.0.1:8090/api/getFileInfo/"+uuid;
        try {
            URL url = new URL(downFileUrl);
            System.out.println("================连接==================");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            System.out.println("================连接成功==================");
            // 设置为POST情  
            conn.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行  
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);

            //获取服务端返回的数据
            InputStream inout = conn.getInputStream();
            ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
            int bytesout = 0;
            byte[] bufferout = new byte[1024];
            while ((bytesout = inout.read(bufferout)) != -1) {
                infoStream.write(bufferout, 0, bytesout);
            }
            inout.close();
            infoStream.flush();
            infoStream.close();
            //对JSON格式的返回数据进行处理
            String json = infoStream.toString("utf-8");
            if(json!=null){
                JSONObject jsonObj = JSONObject.parseObject(json);
                Map<String,String> fileInfo = (Map)jsonObj.get("data");
                String id = fileInfo.get("id");
                String fileUrl = fileInfo.get("fileUrl");
                String createTime = fileInfo.get("createTime");
                String originalName = fileInfo.get("originalName");
                String extensionName = fileInfo.get("extensionName");
                String fileName = fileInfo.get("fileName");
                System.out.println("================文件元信息==================");
                System.out.println("文件ID："+id);
                System.out.println("文件存储地址："+fileUrl);
                System.out.println("文件名称："+fileName);
                System.out.println("原始文件名称："+originalName);
                System.out.println("文件类型："+extensionName);
                SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
                //对文件的创建日期进行格式化
                Date date = new Date();
                try {
                    date = sdf.parse(createTime);
                    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
                    String createTimeFormat = sdf2.format(date);
                    System.out.println("创建时间："+ createTimeFormat);
                }catch (Exception e){
                    System.out.println("格式化日期失败！" + e);
                    e.printStackTrace();
                }
            }
        }catch (Exception e){
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
        }


    }

}
